/*
Copyright 2011 Christian Dadswell
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

package uk.co.chrisdadswell.bbcbc;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnKeyListener;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;

public class Activity_Dashboard extends ListActivity implements Runnable { 
	
	final static String APP_TAG = "BBCBC";
	final static String ACT_TAG = "Dashboard: ";
	final static Date todayDate = new Date();
	static String todayDay = null;
	static String fileDay = null;
	static ArrayList<HashMap<String,String>> stationNameArrayList = new ArrayList<HashMap<String,String>>();
	private ProgressDialog progressDialog;
	SharedPreferences _PREFS;
     
    @Override
    public void onDestroy() {
    	super.onDestroy();
    	Log.d(APP_TAG, ACT_TAG + "... OnDestroy ...");
    	clearDashList();
    	Log.d(APP_TAG, ACT_TAG + "ONDESTROY: Clearing Dashlist");
    }
	 
     // CREATE
    @SuppressWarnings("unchecked")
    @Override 
    public void onCreate(Bundle icicle) { 
    	 super.onCreate(icicle); 
    	 setContentView(R.layout.dashboard);
    	 Context dashboard = this;
    	 _PREFS = PreferenceManager.getDefaultSharedPreferences(this);
    	 
    	 createAppDirectory();
    	 Init();
    	 populateDashList();
         
    	 ImageView rssUrl = (ImageView) findViewById(R.id.img_rss);    	 
    	 rssUrl.setOnClickListener(new View.OnClickListener() {
    		 public void onClick(View v) {
    			 Intent stationURL_intent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse(Constants.urlRss));
    			 startActivity(stationURL_intent);
    		 }
    	 });        
	
    	 ImageView twitterUrl = (ImageView) findViewById(R.id.img_twitter);
    	 twitterUrl.setOnClickListener(new View.OnClickListener() {
    		 public void onClick(View v) {
    			 Intent stationURL_intent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse(Constants.urlTwitter));
    			 startActivity(stationURL_intent);
    		 }
    	 });        
    	 
    	 // SETUP VIEW
         TextView blogUrl = (TextView) findViewById(R.id.tv_Footer);
         blogUrl.setOnClickListener(new View.OnClickListener() {
        	 public void onClick(View v) {
        		 Intent stationURL_intent = new Intent(android.content.Intent.ACTION_VIEW,Uri.parse(Constants.urlBlog));
        		 startActivity(stationURL_intent);
        	 }
         });        

         final TextView wSearch = (TextView) this.findViewById(R.id.txt_search);          
         wSearch.setOnKeyListener(new OnKeyListener() {
        	  public boolean onKey(View v, int keyCode, KeyEvent event) {
        		  if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
        			  String searchString = wSearch.getText().toString(); 
        			  if(searchString != null && searchString.trim().length() == 0) {
        				  Toast.makeText(Activity_Dashboard.this, "\n\nPlease enter a search term, i.e., 'News'\n\n", Toast.LENGTH_SHORT).show();
        				  return false;
        			  }else{
        				  Intent byPodcast_intent = new Intent();
	        			  byPodcast_intent.setClass(v.getContext(), Activity_ByPodcast.class);
	        			  byPodcast_intent.putExtra("SearchString", searchString.trim());
	        			  startActivity(byPodcast_intent);
	        			  wSearch.setText("");
	        			  return true;
        			  }
        		  }
        		  return false;
        	  }
          });
         
         Log.d(APP_TAG, ACT_TAG + "ONCREATE: Showing Dashboard");
    	 SimpleAdapter dashAdapter = new SimpleAdapter(dashboard,dash_list,R.layout.dash_rows,
    			 new String[] {"option", "desc"},new int[] {R.id.text1, R.id.text2});
    	 setListAdapter(dashAdapter);
    	 getListView().setTextFilterEnabled(true);
    	 getListView().setSmoothScrollbarEnabled(true);
    	 getListView().setFadingEdgeLength(60);
     } // END OF ONCREATE
	 
	public boolean Init() {
		Log.d(APP_TAG, ACT_TAG + "METHOD: Init()");
     	// CHECK IF XML HAS BEEN ALREADY DOWNLOADED
        if(!Func_FileIO.FileOrDirectoryExists(Constants.mainxml)) {
        	Log.d(APP_TAG, ACT_TAG + "INIT: XML doesn't exist");
        	if(isInternetOn()) {
        		progressDialog = ProgressDialog.show(this, "Accessing the BBC", "Downloading BBC Podcast listings", true, false);
        		Thread thread = new Thread(Activity_Dashboard.this);
        		thread.start();
        		return true;
        	}else{
        		noInternetDialog("No Internet Connection", "Unable to download Podcast listings.\n\nThere appears to be no internet connection.\n\nPlease connect to the internet\nand relaunch BrowseCast.");
        		return false;
        	}
        }else{ // XML EXISTS, WHATS THE TIME STAMP OF THE FILE
        	Log.d(APP_TAG, ACT_TAG + "INIT: XML exists");
        	if (getFileDay().equals(getTodayDay())){
        		Log.d(APP_TAG, ACT_TAG + "INIT: XML has already been downloaded today");
        		if(getFileSize() != 0) { // DOWNLOADED TODAY ALREADY AND NOT 0 BYTES START ACTIVITY_BYSTATION
        			Log.d(APP_TAG, ACT_TAG + "INIT: XML downloaded and not 0 bytes, display dashboard");
        			return true;
        		}else{ // FILE AVAILABLE. BUT IS 0 BYTES. NEED TO CHECK INTERNET AND DOWNLOAD
        			Log.d(APP_TAG, ACT_TAG + "INIT: XML exists, but is 0 bytes, attempt re-download if internet available");
        			if(isInternetOn()) {
        				Log.d(APP_TAG, ACT_TAG + "INIT: Internet available, downloading ...");
        				progressDialog = ProgressDialog.show(this, "Corrupt local XML found...", "Downloading latest BBC Podcasts listings", true, true);
        				Thread thread = new Thread(this);
        				thread.start();
        				return true;
        			}else{ // NO INTERNET, RAISE AN ALERT AND FORCE USER TO QUIT
        				Log.d(APP_TAG, ACT_TAG + "INIT: No internet, display No internet dialog and quit");
        				noInternetDialog("No internet connection", "A new Podcast listings file needs to be downloaded, but there appears to be no internet connection.\n\nPlease connect to the internet\nand relaunch BrowseCast.");
        			}
        		}
        	}else{ // OUT OF DATE XML, CHECK INTERNET AND RE-DOWNLOAD THE FILE
        		Log.d(APP_TAG, ACT_TAG + "INIT: XML is a day old, re-download file is internet available");
        		if(isInternetOn()) {
        			Log.d(APP_TAG, ACT_TAG + "INIT: Internet available, downloading ...");
        			progressDialog = ProgressDialog.show(this, "Local listings out of date", "Downloading latest Podcast listings", true, false);
        			Thread thread = new Thread(this);
        			thread.start();
        			return true;
        		}else{
        			noInternetNoQuitDialog("No internet connection", "A new Podcast listings file is available, " +
        					"but there appears to be no internet connection to download it.\n" +
        					"You can carry on using the current listings by selecting Dashboard.\n" +
        					"Or connect to the internet\nand relaunch BrowseCast to download the new file.");
        			return false;
        		}
        	}
        }
        return false;
	}

	public void run() {
	boolean msgResult = false;
	Log.d(APP_TAG, ACT_TAG + "RUN: Starting download of XML file ...");
	msgResult = Func_Download.DownloadFile("http://www.bbc.co.uk/podcasts.xml", Constants.xmldir);
	if(msgResult == true){
		Log.d(APP_TAG, ACT_TAG + "RUN: Thread Successful");
		MainXMLDownloadHandler .sendMessage(Message.obtain(MainXMLDownloadHandler , 1));
	}else{
		Log.d(APP_TAG, ACT_TAG + "RUN: Thread Unsuccessful");
		MainXMLDownloadHandler .sendMessage(Message.obtain(MainXMLDownloadHandler , 0));
	}
}

	private Handler MainXMLDownloadHandler = new Handler() {
    @Override
    public void handleMessage(Message msg) {
   	 Log.d(APP_TAG, ACT_TAG + "HANDLER: The message is: " + msg);
   	 switch(msg.what) {
   	 case 0: // UNSUCCESSFUL
   		Log.d(APP_TAG, ACT_TAG + "HANDLER: Download Unsuccessful");
   		progressDialog.dismiss();
   		noInternetDialog("Cannot download file", "A BBC Podcast listings file needs to be downloaded, but there appears to be no internet connection.\n\nPlease connect to the internet\nand relaunch BrowseCast.");
   		break;
   	 case 1: // SUCCESSFULL
   		Log.d(APP_TAG, ACT_TAG + "HANDLER: Download successful");
   		progressDialog.dismiss();
   		break;
   	 }
    }
};

	ArrayList<HashMap<String,String>> dash_list = new ArrayList<HashMap<String,String>>();
	private void populateDashList() {
		 Log.d(APP_TAG, ACT_TAG + "DASHBOARD: Adding options to dashboard");
		 // 0
		 HashMap<String,String> temp0 = new HashMap<String,String>();
		 temp0.put("option","Browse Podcasts by Station");
		 temp0.put("desc", "View available BBC Radio stations");
		 dash_list.add(temp0);

		 // 1
		 HashMap<String,String> temp1 = new HashMap<String,String>();
		 temp1.put("option","5Live Podcasts");
		 temp1.put("desc", "5Live Podcasts Website");
		 dash_list.add(temp1);
		 
		 // 2
		//	 HashMap<String,String> temp1 = new HashMap<String,String>();
		//	 temp1.put("option","Browse Podcasts by Genre");
		//	 temp1.put("desc", "View available BBC Radio genres");
		//	 dash_list.add(temp1);
		 HashMap<String,String> temp2 = new HashMap<String,String>();
		 temp2.put("option","Olympics 5Live Podcasts");
		 temp2.put("desc", "London 2012 Olympics 5Live Podcasts");
		 dash_list.add(temp2);
	
		 // 3
		 HashMap<String,String> temp3 = new HashMap<String,String>();
		 temp3.put("option","Listen Live");
		 temp3.put("desc", "Listen Live to available* BBC stations");
		 dash_list.add(temp3);

		 // 4
		 HashMap<String,String> temp4 = new HashMap<String,String>();
		 temp4.put("option","Radio Schedules");
		 temp4.put("desc", "View BBC Radio scheduling information");
		 dash_list.add(temp4);
	}
	 
	@Override
	protected void onListItemClick(ListView listView, View view, int position, long id) {
		    super.onListItemClick(listView, view, position, id);
		    if(id == 0) {
		    	Intent intentStation = new Intent(Activity_Dashboard.this, Activity_ByStation.class);
		    	Activity_Dashboard.this.startActivity(intentStation);
		    }else if(id == 1){
		    	Intent fivelive_intent = new Intent(Intent.ACTION_VIEW); 
				fivelive_intent.setData(Uri.parse("http://www.bbc.co.uk/podcasts/5live.mp"));
				startActivity(fivelive_intent);
//		    	Intent intentGenre = new Intent(Activity_Dashboard.this, Activity_ByGenre.class);
//		    	Activity_Dashboard.this.startActivity(intentGenre);
		    }else if(id == 2){
		    	Intent olympics_intent = new Intent(Intent.ACTION_VIEW); 
				olympics_intent.setData(Uri.parse("http://downloads.bbc.co.uk/podcasts/radio/olympics/rss.xml"));
				startActivity(olympics_intent);
		    }else if(id == 3){
		    	Intent intentListenLive = new Intent(Activity_Dashboard.this, Activity_ListenLive.class);
		    	Activity_Dashboard.this.startActivity(intentListenLive);
		    }else if(id == 4){
		    	Intent intentSchedules = new Intent(Activity_Dashboard.this, Activity_Schedules.class);
		    	Activity_Dashboard.this.startActivity(intentSchedules);
		    }
//		    }else if(id == 4) {
//		    	Intent intentBritify = new Intent(Activity_Dashboard.this, Activity_Britify.class);
//		    	Activity_Dashboard.this.startActivity(intentBritify);
//		    }
	}
		
	// PREPARE OPTIONS MENU
	public boolean onPrepareOptionsMenu(Menu menu) {
		menu.clear();
		menu.add(0,Constants.MENU_PREFERENCES,0,"Help / Support").setIcon(R.drawable.preferences);
		menu.add(0,Constants.MENU_DELETEXML,0,"Reload Podcast Listings").setIcon(R.drawable.folder);
		return super.onPrepareOptionsMenu(menu);
	}// END OF OPTIONS MENU
		
	@Override
	public boolean onOptionsItemSelected (MenuItem item){
		switch (item.getItemId()){
		case Constants.MENU_PREFERENCES:
			Intent prefsActivity = new Intent(Activity_Dashboard.this, Activity_Preferences.class);
			startActivity(prefsActivity);
			break;
		case Constants.MENU_DELETEXML:
			boolean isDeleted = Func_FileIO.DeleteFile(Constants.mainxml);
			if(isDeleted){
				Log.d(APP_TAG, ACT_TAG + "ONOPTIONSITEMSELECTED: Deleting and re-downloading podcast listings XML");
				Log.d(APP_TAG, ACT_TAG + "ONOPTIONSITEMSELECTED: Clearing ArrayList");
				resetData();
				Init();
			}else{
				Log.d(APP_TAG, ACT_TAG + "ONOPTIONSITEMSELECTED: Couldn't delete local XML file, finishing BBCBC");
				finish();
			}
			break;
		}
		return false;
	}
	   
     // CHECK INTERNET METHOD
     public final boolean isInternetOn() {
    	 Log.d(APP_TAG, ACT_TAG + "ISINTERNETON: Checking connectivity ...");
         ConnectivityManager connec =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
     	 if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED || connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTING || connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTING || connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED ) {
     		Log.d(APP_TAG, ACT_TAG + "ISINTERNETON: Connectivity available: "); 
     		Log.d(APP_TAG, ACT_TAG + "3G = " + connec.getNetworkInfo(0).getState().toString());
     		Log.d(APP_TAG, ACT_TAG + "WiFi = " + connec.getNetworkInfo(1).getState().toString());
     		return true; 
 		 } else if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.DISCONNECTED ||  connec.getNetworkInfo(1).getState() == NetworkInfo.State.DISCONNECTED  ) {
 			Log.d(APP_TAG, ACT_TAG + "ISINTERNETON: No connectivity");
     		Log.d(APP_TAG, ACT_TAG + "3G = " + connec.getNetworkInfo(0).getState().toString());
     		Log.d(APP_TAG, ACT_TAG + "WiFi = " + connec.getNetworkInfo(1).getState().toString());
 			return false;
 		 }
 		return false;   	 
      }
     
     // DIALOGS
     protected void noInternetDialog(String title, String message) { 
    	 Log.d(APP_TAG, ACT_TAG + "NOINTERNETDIALOG: No internet");
    	 AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
    	 alertbox.setMessage(message) 
    	 .setTitle(title) 
    	 .setCancelable(true) 
     	 .setIcon(R.drawable.alert)
    	 .setNeutralButton("Quit", new DialogInterface.OnClickListener() { 
    		 public void onClick(DialogInterface dialog, int whichButton){
    			 finish();
    		 }
    	 });
    	 alertbox.show(); 
     }

     protected void noInternetNoQuitDialog(String title, String message) { 
    	 Log.d(APP_TAG, ACT_TAG + "NOINTERNETNOQUITDIALOG: No InternetNoQuit");
    	 AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
    	 alertbox.setMessage(message) 
    	 .setTitle(title) 
    	 .setCancelable(true) 
     	 .setIcon(R.drawable.alert)
     	 .setPositiveButton("Dashboard", new DialogInterface.OnClickListener() { 
    		 public void onClick(DialogInterface dialog, int whichButton){
    			 Log.d(APP_TAG, ACT_TAG + "NOINTERNETNOQUITDIALOG: Using existing XML file");
    			 dialog.dismiss();
    		 }
     	 })
    		 
     	 .setNeutralButton("Quit", new DialogInterface.OnClickListener() { 
    		 public void onClick(DialogInterface dialog, int whichButton){
    			 Log.d(APP_TAG, ACT_TAG + "DIALOG: Quitting BBCBC");
    			 finish();
    		 }
    	 });
    	 alertbox.show(); 
     }

     private void createAppDirectory() {
    	 Log.d(APP_TAG, ACT_TAG + "CREATEAPPDIRECTORY: Create application directory");
    	 Func_FileIO.CreateDirectory(Constants.appdir);
         Func_FileIO.CreateDirectory(Constants.xmldir);
     }
     
     private long getFileSize() {
    	 long fileSize = Func_FileIO.FileSize(Constants.mainxml);
    	 return fileSize;
     }

     private String getFileDay() {
 		Date fileDate = Func_FileIO.FileLastModified(Constants.mainxml); // GET DAY OF THE WEEK FOR LAST FILE DOWNLOAD
  		fileDay = Func_Date.GetDayofTheDate(fileDate);
  		return fileDay;
     }

     private String getTodayDay() {
    	 String todayDay = Func_Date.GetDayofTheDate(todayDate);
    	 return todayDay;
     }
     
     private void clearDashList() {
    	 dash_list.clear();
     }

 	private final void resetData() {
		Log.d(APP_TAG, ACT_TAG + "RESETDATA: Clearing ArrayLists");
		Activity_ByStation.ARRAYLIST_STATUS = false;
		Activity_ByStation.stationNameArrayList.clear();
		Activity_ByGenre.ARRAYLIST_STATUS = false;
		Activity_ByGenre.genreNameArrayList.clear();
	}
     
} // END OF ACTIVITY CLASS